package Testdemo2;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:周次煜
 * Date: 2024-05-03
 * Time：10:36
 */
public class Test6 {
    public static int lengthOfLongestSubstring(String s) {
        int sz = s.length();
        int left = 0, right = 0;
        int len = 0;
        Map<Character, Integer> map = new HashMap<>();

        /**
         * 先用 hashmap 计算 走过的大小
         * 一但走过的right的值 ++
         * 一旦超过 1 的就让 left 把对应值 --
         *  直到找到那个 right 的值减到 1 为止
         *  就意味着跳过了 该重复着
         */

        for (; right < sz; right++) {
            char chr=s.charAt(right);
            if (map.containsKey(chr)) {
                int i=map.get(chr);
                map.put(chr,i+1);
            } else  {
                map.put(chr,1);
            }


            while(map.get(chr) > 1) {
                char chl=s.charAt(left);
                map.put(chl,map.get(chl)-1);
                left++;

            }

            len=Math.max(len,right-left+1);

        }
        return len;

    }


    public static void main1(String[] args) {
        String s=new String("pwwkew");
        System.out.println(lengthOfLongestSubstring(s));
    }

    /**
     * 计算最大连续 1 的长度
     * 利用统计 0 和 k 的个数比较来
     * 进行滑动窗口的实现
     * @param nums 整型数组
     * @param k 目标值
     * @return 返回值
     */

        public  static int longestOnes(int[] nums, int k) {
            int sz=  nums.length;
            if(k >= sz) return sz;
            int sum=0,zero=0;
            int ret=0;
            for(int left=0, right=0; right < sz ;right++) {

                // 统计 0 的个数来进窗口
                if(nums[right] == 0) {
                    zero++;
                }

                // 通过 0 的个数和 k的大小比较 来出窗口
                while(zero > k) {

                    if(nums[left]==0) {
                        zero--;
                    }
                    left++;

                }


                ret=Math.max(right-left+1,ret);
            }


            return ret;
        }

    /**
     * 讲 x 减到 0 的最小操作数
     *  首先 建立 正难则反的思维
     *  然后 求把本来是两边 的 总和 的长度
     *   转化为 求中间连续长度 的目标值的差值来计算
     *   中间连续长度就可以利用我们的滑动窗口来实现
     * @param nums 整型数组
     * @param x 目标值
     * @return 返回等于目标值的长度
     */

    public static int minOperations(int[] nums, int x) {
        int sz=nums.length;
        int sum=0;
        for(int i=0; i< sz ; i++) {
            sum += nums[i];
        }

        // 如果全部总和 为  x 就返回 总长度
        if(sum==x) return sz;

        int target = sum - x;
        int len=0;
        sum=0;
        for(int left=0,right=0; right < sz ; right++) {

            // 先入窗口
            sum += nums[right];

            // 一旦 总和过大 就 出窗口
            while(left < sz && sum > target) {
                sum -= nums[left];
                left++;
            }

            // 总和 等于 目标值 就更新结果
            if(sum==target) {
                len=Math.max(len,right-left+1);
            }
        }

        //  len=0 就说明找不到等于 target 的长度， 就返回 -1
        if(len==0) return -1;

        // 找到了就返回 总长度 减去 目标长度 的差值
        return sz-len;


    }

    /**
     * 水果成篮
     * 找出两种不同数字的子数组的最大长度
     * 利用滑动窗口解题
     * 首先通过前 两种 数字的出现的次数
     * 当 出现第三个数字时，就一一出窗口
     * left ++ 直到 为 0 时，删除 该 数字
     * @param fruits 水果数组
     * @return 返回最长的两种类型的的水果
     */
    public int totalFruit(int[] fruits) {
        int sz=fruits.length;

        int len=0;

        Map<Integer,Integer> map=new  HashMap<>();
        for(int right=0,left=0; right < sz; right++) {

            // 利用哈希表 统计前两种数字的出现的次数
            if(map.containsKey(fruits[right])) {
                map.put(fruits[right],map.get(fruits[right])+1);
            } else {
                map.put(fruits[right],1);
            }

            // 当次数 大于2 时 就一个一个 减少出现次数
            while (map.size() > 2 ) {
                map.put(fruits[left] , map.get(fruits[left])-1);

                // 当出现次数 为 0 时 就删除 该 类型的数字
                if( map.get(fruits[left]) <= 0) {
                    map.remove(fruits[left]);

                }
                // left 一直往右走
                left++;
            }

            // 更新结果
            len=Math.max(len,right-left+1);
        }


        return len;
    }


    public static void main2(String[] args) {
        System.out.println(findAnagrams("abab", "ab"));
        String s=new String("abciopwe");
        System.out.println(s.substring(0, 3).equals("abc"));
        Map<Integer,Integer> map=new HashMap<>();


    }
    public static List<Integer> findAnagrams(String s, String p) {
        List<Integer> list=new ArrayList<>();
        int sz=s.length();
        int pz=p.length();

        // s 的 set1
        Map<Character,Integer> map1= new HashMap<>();

        // p 的 set2
        Map<Character,Integer> map2= new HashMap<>();

        // 将  p 中的所有元素全部 入set
        for(int i=0; i< pz ; i++) {
           char ch= p.charAt(i);
            if (map2.containsKey(ch)) {
                map2.put(ch,map2.get(ch)+1);
            } else  {
                map2.put(ch,1);
            }
        }

        // 开始进行 固定滑动窗口
        for(int left=0,right=0; right< sz ; right++) {

            // 先入窗口
            char ch= s.charAt(right);
            if (map1.containsKey(ch)) {
                map1.put(ch,map1.get(ch)+1);
            } else  {
                map1.put(ch,1);
            }

            // 判断
            if(right-left + 1 > pz) {
                // 出窗口
                char ch1=s.charAt(left);
                map1.put(ch1,map1.get(ch1)-1);
                if (map1.get(ch1) <= 0) {
                    map1.remove(ch1);
                }
                left++;
            }

            // 检验结果
            if(map1.equals(map2)) {
                list.add(left);

            }
        }

        return list;
    }

    public static boolean isSubsequence(String s, String t) {
        int sz=s.length();
        int tz=t.length();

        /*
         * 特殊情况判断
         * 如果目标序列为空 就为真
         * 如果 判断序列为空，就返回假
         * 注意先后顺序
         */
        if(sz==0) return true;
        if(tz==0) return false;

        int cur=0,dest=0;
        // 定义两个指针
        while(cur < tz && dest < sz) {
            // 一旦两个指针相等就一起走
            if(s.charAt(dest)==t.charAt(cur)) {
                dest++;
                cur++;
            } else {
                // 不相等就让判断序列先走
                cur++;
            }
        }

        // 最终只要判断 目标序列是否走完即可
        return dest >= sz;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();

        // 首先建立一个栈来存储元素进行先进后出
        Stack<Character> stack= new Stack<>();


        for(int i=0; i< s.length(); ) {

            // 一旦栈存在该元素就 出栈
            if(stack.isEmpty()) {
                stack.add(s.charAt(i));
                i++;
            }

            if (i >= s.length()) break;

            if(stack.peek()==s.charAt(i)) {
                stack.pop();
                i++;
            } else {
                // 不存在就入栈
                stack.add(s.charAt(i));
                i++;
            }

        }

        // 建立一个打印的栈
        // 让栈里面的元素实现先进先出
        Stack<Character> print=new Stack<>();
        while(!stack.isEmpty()) {
            print.add(stack.pop());
        }

        while(!print.isEmpty()) {
            System.out.print(print.pop());

        }


    }

}
